/**
 * Copyright (C), 2015-2024, XXX有限公司
 * FileName: SrcDbThread
 * Author:   mac
 * Date:     2024/3/7 15:32
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.finsiot.tools.taos.migration;

import com.finsiot.tools.taos.migration.bean.TableRelation;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author zhangtianchang
 * @create 2024/3/7
 * @since 1.0.0
 */
@Slf4j
public class ExportMeta {

    private final static String ddl = "/meta";

    private FileWriter fw;

    Statement statement;

    Connection connection;

    String filePath;

    @Getter
    List<String> tableList=new ArrayList<>();

    public ExportMeta(Connection connection,String filePath) {

        this.connection=connection;

        File ddlFile = new File(filePath + ddl);
        if (!ddlFile.getParentFile().exists()) {
            ddlFile.getParentFile().mkdir();
        }
        if (ddlFile.exists()) {
            ddlFile.delete();
        }
        ddlFile.mkdir();

        this.filePath=filePath;

        tableList.addAll(getTables());
    }

    private List<String> getTables()  {
        String sql = "show tables";
        List<String> tabelList = new ArrayList<>();
        try {

        statement = connection.createStatement();
        // executeQuery
        ResultSet tempResultSet = statement.executeQuery(sql);
        ResultSetMetaData metaData = tempResultSet.getMetaData();
        while (tempResultSet.next()) {
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                String value = tempResultSet.getString(i);
                tabelList.add(value);
            }
        }

        statement.close();
        }catch (SQLException e){
            e.printStackTrace();
        }

        return tabelList;
    }

    public List<String> getSuperTables() throws SQLException {
        statement = connection.createStatement();

        String sql = "show stables";
        List<String> stabelList = new ArrayList<>();
        // executeQuery
        ResultSet tempResultSet = statement.executeQuery(sql);
        ResultSetMetaData metaData = tempResultSet.getMetaData();
        while (tempResultSet.next()) {
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                String value = tempResultSet.getString(i);
                stabelList.add(value);
            }
        }
        statement.close();
        return stabelList;
    }

    public void exportMeta(HashMap<String, TableRelation> tableRelationHashMap) throws SQLException, IOException {

        statement = connection.createStatement();
        String tableInfoSql = "show create table %s";
        int i=0;
        int n=0;
        for (String stable : tableRelationHashMap.keySet()) {
            ResultSet tempResultSet1 = statement.executeQuery(String.format(tableInfoSql, stable));

            fw = new FileWriter(filePath+ddl+"/"+stable+".sql");
            while (tempResultSet1.next()) {

                fw.write(String.format("# stable `%s`\n", tempResultSet1.getString(1)));
                fw.write(String.format("DROP TABLE IF EXISTS %s;\n", tempResultSet1.getString(1)));
                queryTable(statement,tableInfoSql,stable,fw);
                i++;
            }
            tempResultSet1.close();

            for(String table:tableRelationHashMap.get(stable).getSonTableList()){
                queryTable(statement,tableInfoSql,table,fw);
                n++;
            }
            fw.flush();
            fw.close();

        }
        statement.close();
        log.info("总计导出超级表:{},子表：{}",i,n);

    }

    private void queryTable(Statement statement, String tableInfoSql, String table, FileWriter fw) throws SQLException, IOException {
        ResultSet tempResultSet2 = statement.executeQuery(String.format(tableInfoSql, table));

        while (tempResultSet2.next()) {
            fw.write(tempResultSet2.getString(2) + ";\n");
        }
        tempResultSet2.close();
    }

    public TableRelation getSonTableInfo(String table)  {


        List<String> tagList = new ArrayList<>();
        List<String> tagValueList = new ArrayList<>();

        List<String> sonTableList= new ArrayList<>();

        try {
            Statement statement = connection.createStatement();
            ResultSet  rs =statement.executeQuery("SHOW table TAGS  from "+table);
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount=  rs.getMetaData().getColumnCount();
            while (rs.next()) {
                String tableName=rs.getNString(1);
                sonTableList.add(tableName);
                if(tableList.contains(tableName)){
                    tableList.remove(tableName);
                }
                for (int i = 2; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    if(!tagList.contains(columnName)) {
                        tagList.add(columnName);
                        tagValueList.add(rs.getNString(i));
                    }
                }
            }
            rs.close();

        }catch (SQLException e){
            e.printStackTrace();
        }
        return new TableRelation(table,tagList,tagValueList,sonTableList);
    }

}
